cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# init project version and product version
project(AMCAXExchange VERSION 0.0.1)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=1")

# Check glibc version
set(USE_CONAN ON)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  include(${CMAKE_SOURCE_DIR}/cmake/check_glibc_version.cmake)
  set(REQUIRED_GLIBC_VERSION 235) # 表示 2.28
  get_glibc_version()
  
  if(${CURRENT_GLIBC_VERSION} LESS ${REQUIRED_GLIBC_VERSION})
    set(USE_CONAN OFF)
  endif()
  message(USE_CONAN -> ${USE_CONAN})
endif()

include(${CMAKE_SOURCE_DIR}/cmake/set_product_version.cmake)

if(WIN32)
  add_compile_definitions(_USE_MATH_DEFINES)
  add_compile_options("/std:c++17")
endif()

include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_SOURCE_DIR}/include)

file(GLOB_RECURSE PROJECT_SRC src/*.cpp)

if(NOT CMAKE_TOOLCHAIN_FILE)
  set(CONAN_DIR ${CMAKE_SOURCE_DIR}/.conan/${CMAKE_BUILD_TYPE})
  include(${CONAN_DIR}/conan_toolchain.cmake)
endif()

# spdlog
find_package(spdlog REQUIRED)
list(APPEND PRIVATE_LIBRARIES spdlog::spdlog)

# json
find_package(nlohmann_json REQUIRED)
list(APPEND PRIVATE_LIBRARIES nlohmann_json::nlohmann_json)

if(AMCAXDxf  STREQUAL "on")
  add_definitions(-DAMCAX_DXF_ENABLE)
endif()

if(AMCAXDwg  STREQUAL "on")
  add_definitions(-DAMCAX_DWG_ENABLE)
endif()

if(AMCAXGltf  STREQUAL "on")
  add_definitions(-DAMCAX_GLTF_ENABLE)
endif()

if(AMCAXObj  STREQUAL "on")
  add_definitions(-DAMCAX_OBJ_ENABLE)
endif()

if(AMCAXStep  STREQUAL "on")
  add_definitions(-DAMCAX_STEP_ENABLE)
endif()

if(AMCAXStl  STREQUAL "on")
  add_definitions(-DAMCAX_STL_ENABLE)
endif()

if(AMCAXBrep  STREQUAL "on")
  add_definitions(-DAMCAX_BREP_ENABLE)
endif()

if(AMXStorage STREQUAL "on")
  # AMXStorage
  add_definitions(-DAMXSTORAGE_ENABLE)
endif()


if(${USE_CONAN})
  # kernel
  find_package(AMCAXCommon REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXCommon)

  find_package(AMCAXStep REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXStep)

  find_package(AMCAXOCCTIO REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXOCCTIO)

  find_package(AMCAXPart REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXPart)

  # gltf
  find_package(AMCAXGltf REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXGltf)

  # Dxf
  find_package(AMCAXDxf REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXDxf)

  # Dwg
  find_package(AMCAXDwg REQUIRED)
  list(APPEND PUBLIC_LIBRARIES AMCAXDwg)

  if(AMXStorage STREQUAL "on")
    # AMXStorage
    add_definitions(-DAMXSTORAGE_ENABLE)
    find_package(AMCAXStorage REQUIRED)
    list(APPEND PUBLIC_LIBRARIES AMCAXStorage)
  endif()
else()
  
  if(DEFINED ENV{AMCAX_PATH})
    set(3rd $ENV{AMCAX_PATH})
  else()
    set(3rd ${CMAKE_SOURCE_DIR}/3rd)
  endif()
  set(AMCAXCOMMON_DIR ${3rd}/AMCAXCommon)
  set(AMCAXPART_DIR ${3rd}/AMCAXPart)
  set(AMCAXSTEP_DIR ${3rd}/AMCAXStep)

  install(DIRECTORY ${AMCAXCOMMON_DIR} DESTINATION 3rd/)
  install(DIRECTORY ${AMCAXPART_DIR} DESTINATION 3rd/)
  install(DIRECTORY ${AMCAXSTEP_DIR} DESTINATION 3rd/)
  
  include_directories(${AMCAXCOMMON_DIR}/include)
  include_directories(${AMCAXPART_DIR}/include)
  include_directories(${AMCAXSTEP_DIR}/include)
  link_directories(${AMCAXCOMMON_DIR}/lib)
  link_directories(${AMCAXPART_DIR}/lib)
  link_directories(${AMCAXSTEP_DIR}/lib)
  list(APPEND PUBLIC_LIBRARIES AMCAXCommon)
  file(GLOB DEPENDLIST ${AMCAXCOMMON_DIR}/lib/*.so)
  list(APPEND LIBRARIES_PATH ${DEPENDLIST})

  list(APPEND PUBLIC_LIBRARIES AMCAXPart)
  file(GLOB DEPENDLIST ${AMCAXPART_DIR}/lib/*.so)
  list(APPEND LIBRARIES_PATH ${DEPENDLIST})

  list(APPEND PUBLIC_LIBRARIES AMCAXOCCTIO)  

  list(APPEND PUBLIC_LIBRARIES AMCAXStep)
  file(GLOB DEPENDLIST ${AMCAXSTEP_DIR}/lib/*.so)
  list(APPEND LIBRARIES_PATH ${DEPENDLIST})

  if(AMXStorage STREQUAL "on")
    # AMXStorage
    set(AMCAXStorage_DIR ${3rd}/AMCAXStorage)
    link_directories(${AMCAXStorage_DIR}/lib)
    message(AMCAXStorage_DIR -> ${AMCAXStorage_DIR})
    include_directories(${AMCAXStorage_DIR}/include)
    list(APPEND PUBLIC_LIBRARIES AMCAXStorage)
    file(GLOB DEPENDLIST ${AMCAXStorage_DIR}/lib/*.so*)
    list(APPEND LIBRARIES_PATH ${DEPENDLIST})
  endif()
endif()

# interOp
if(InterOp STREQUAL "on")
  # source depend
  add_definitions(-DINTEROP_ENABLE)
  set(AMCAX_INTEROP_PATH $ENV{INTEROP_BIN_ROOT})
  set(AMCAX_INTEROP_LIB_BASE $ENV{INTEROP_BIN})
  
  link_directories(${AMCAX_INTEROP_LIB_BASE})
  link_directories(${AMCAX_INTEROP_PATH}/lib)
  message(STATUS "AMCAX_INTEROP_PATH -> ${AMCAX_INTEROP_PATH}")
  include_directories(${AMCAX_INTEROP_PATH}/include)
  # datakit
  set(AMCAX_DATAKIT_PATH $ENV{DATAKIT_BIN_ROOT})
  set(AMCAX_DATAKIT_LIB_BASE $ENV{DATAKIT_BIN})
    
  link_directories(${AMCAX_DATAKIT_LIB_BASE})
  link_directories(${AMCAX_DATAKIT_PATH}/lib)
  include_directories(${AMCAX_DATAKIT_PATH}/include)

  # install depend
  if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    file(GLOB INTEROP_DEPENDLIST ${AMCAX_INTEROP_LIB_BASE}/*.so)
    list(APPEND LIBRARIES_PATH ${INTEROP_DEPENDLIST})

    file(GLOB DATAKIT_DEPENDLIST ${AMCAX_DATAKIT_LIB_BASE}/lib/*.so)
    list(APPEND LIBRARIES_PATH ${DATAKIT_DEPENDLIST})
    
    file(GLOB DATAKIT_DEPENDLIST ${AMCAX_DATAKIT_LIB_BASE}/*.so)
    list(APPEND LIBRARIES_PATH ${DATAKIT_DEPENDLIST})
    list(APPEND PUBLIC_LIBRARIES uuid)
  else()
    list(APPEND DENPEND_DLL_FILES ${AMCAX_INTEROP_LIB_BASE}/AMCAXInterop.dll)  
    # list(APPEND LIBRARIES_PATH ${DENPEND_DLL_FILES})
    
    # message(STATUS "DENPEND_DLL_FILES -> ${DENPEND_DLL_FILES}")
    # message(STATUS "LIBRARIES_PATH -> ${LIBRARIES_PATH}")
    list(APPEND DENPEND_DLL_FILES ${AMCAX_DATAKIT_LIB_BASE}/AMCAXDatakits.dll)  
    
    list(APPEND LIBRARIES_PATH ${DENPEND_DLL_FILES})
    # message(STATUS "DENPEND_DLL_FILES -> ${DENPEND_DLL_FILES}")
    message(STATUS "LIBRARIES_PATH -> ${LIBRARIES_PATH}")
  endif()
  install(DIRECTORY ${AMCAX_INTEROP_PATH}/3rd/ DESTINATION 3rd/)  

  # install(DIRECTORY ${AMCAX_DATAKIT_PATH}/3rd/ DESTINATION 3rd/)  
  
endif()


# add share library
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(${PROJECT_NAME} SHARED ${PROJECT_SRC})

target_link_libraries(${PROJECT_NAME} PUBLIC ${PUBLIC_LIBRARIES})

if(NOT ${USE_CONAN})
  # target_link_libraries(${PROJECT_NAME} PUBLIC  stdc++fs)
  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      message(STATUS "GCC version: ${CMAKE_CXX_COMPILER_VERSION}")

      if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.4)
          
          add_definitions(-DCXX_LESS_17)
      else()
          target_link_libraries(${PROJECT_NAME} PUBLIC  stdc++fs)
      endif()
  endif()
endif()

target_link_libraries(${PROJECT_NAME} PUBLIC ${PRIVATE_LIBRARIES})
if(InterOp STREQUAL "on")
  target_link_libraries(${PROJECT_NAME} PRIVATE AMCAXInterop)
  target_link_libraries(${PROJECT_NAME} PRIVATE AMCAXDatakits)
endif()

target_include_directories(
  ${PROJECT_NAME}
  PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> # 构建时的包含路径
         $<INSTALL_INTERFACE:include> # 安装后的包含路径
)

# copy share lib into CMAKE_CURRENT_BINARY_DIR
include(${CMAKE_SOURCE_DIR}/cmake/copy_conan_libs.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/get_conan_lib_dirs.cmake)
copy_conan_libs(${CMAKE_CURRENT_BINARY_DIR})
copy_conan_libs(${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})

# executable
file(GLOB_RECURSE PROJECT_TEST_SRC test/*.cpp)
add_executable(amcax_exchange_test ${PROJECT_TEST_SRC} )
target_link_libraries(amcax_exchange_test PRIVATE ${PROJECT_NAME}  )
if(NOT ${USE_CONAN})
  # target_link_libraries(amcax_exchange_test PRIVATE stdc++fs  )

  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      message(STATUS "GCC version: ${CMAKE_CXX_COMPILER_VERSION}")

      if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.4)
          add_definitions(-DCXX_LESS_17)
      else()
          target_link_libraries(amcax_exchange_test PRIVATE stdc++fs )
      endif()
  endif()
endif()

add_custom_command(TARGET amcax_exchange_test POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
    $<TARGET_FILE:amcax_exchange_test>  # 这个是生成的 exe 文件路径
    ${CMAKE_BINARY_DIR}/ExchangeHelper  # 目标路径和文件名
)


# install version
if(MSVC)
  set(SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
  configure_file(${CMAKE_SOURCE_DIR}/cmake/Version.rc.in Version.rc)
  target_sources(${PROJECT_NAME} PRIVATE "Version.rc")
else()
  set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "${PROJECT_VERSION}")
endif()

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX
      ${PROJECT_BINARY_DIR}/install/${CMAKE_BUILD_TYPE}
      CACHE PATH "..." FORCE)
endif()

# install target
install(
    TARGETS ${PROJECT_NAME} amcax_exchange_test
    EXPORT ${PROJECT_NAME}Targets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin # LIBRARY DESTINATION bin
)
  
list(LENGTH LIBRARIES_PATH len)
message(STATUS "len -> ${len}")
if(len GREATER 0)
  message (LIBRARIES_PATH -> ${LIBRARIES_PATH})
  foreach(dir IN LISTS LIBRARIES_PATH)
    message(dir -> ${dir})
    # file(COPY ${dir} DESTINATION ${PROJECT_BINARY_DIR}/lib)
    file(COPY ${dir} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
  endforeach()

  install(FILES ${LIBRARIES_PATH} DESTINATION lib)
  # message(LIBRARIES_PATH -> ${LIBRARIES_PATH})
endif()

if(WIN32)
  install(DIRECTORY 3rd/ DESTINATION 3rd/)  
endif()


list(APPEND DENPEND_DLL_FILES ${LIBRARIES_PATH})
install(DIRECTORY include/ DESTINATION include)
install(DIRECTORY test/ DESTINATION test)
install(FILES ${DENPEND_DLL_FILES} DESTINATION lib/)
install(FILES ${CMAKE_BINARY_DIR}/ExchangeHelper DESTINATION bin/)
# install lib cmake config
# include(${CMAKE_SOURCE_DIR}/cmake/install_project_cmake_config.cmake)
